package emp;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.Before;
import org.junit.Test;

public class EmpTest {

	List<Emp> emps = new ArrayList<>();
	
	@Before
	public void init() {
		//              员工编号，员工名      职位      经理编号           入职日期                                  工资 奖金 部门编号
		//               empno  ename   job   mgr        hiredate             sal comm deptno
		emps.add(new Emp(7369,"smith","clerk",7902,LocalDate.of(1980, 12, 17),800,0,20));
		emps.add(new Emp(7354,"martin","salesman",7698,LocalDate.of(1981, 9, 28),1250,1400,30));
		emps.add(new Emp(7521,"ward","salesman",7698,LocalDate.of(1981, 2, 22),1250,500,30));
		emps.add(new Emp(7499,"allen","salesman",7698,LocalDate.of(1981, 2, 20),1600,300,30));
		emps.add(new Emp(7839,"king","president",0,LocalDate.of(1981, 11, 17),5000,0,10));
		emps.add(new Emp(7844,"turner","salesman",7698,LocalDate.of(1981, 9, 8),1500,0,30));
		emps.add(new Emp(7902,"ford","analyst",7566,LocalDate.of(1981,12,3),3000,0,20));
		emps.add(new Emp(7900,"james","clerk",7698,LocalDate.of(1981, 12, 3),1100,0,30));
		emps.add(new Emp(7934,"miller","clerk",7782,LocalDate.of(1982, 1, 23),1300,0,10));
		emps.add(new Emp(7782,"clark","manager",7839,LocalDate.of(1981,6,9),2450,0,10));
		emps.add(new Emp(7698,"Blake","manager",7839,LocalDate.of(1981,05,01),2850,0,30));
		emps.add(new Emp(7566,"jones","manager",7839,LocalDate.of(1981, 4, 2),2975,0,20));
		emps.add(new Emp(7876,"adams","clerk",7788,LocalDate.of(1987, 5, 23),1100,0,20));
		emps.add(new Emp(7788,"scott","analyst",7566,LocalDate.of(1987, 4, 19),3000,0,20));
	}
	
	@Test
	public void test1() {
		// 1.统计一共多少个员工
		long count = emps.stream().count();
		System.out.println(count);
		System.out.println("------------------");
		// 2.按照工资从小到大排序     要想直接调用sorted()那么Emp类必须实现Comparable接口
		Stream<Emp> sorted = emps.stream().sorted();
		sorted.forEach(e -> System.out.println(e));
		System.out.println("------------------");
		
		// 如果不实现Comparable接口，就自己实现比较器
		Stream<Emp> sorted2 = emps.stream().sorted((o1,o2)->o1.getSal() - o2.getSal());
		sorted2.forEach(e -> System.out.println(e));
		System.out.println("------------------");
		
		// 3.要前5个人
		emps.stream().limit(5).forEach(s -> System.out.println(s));
		System.out.println("------------------");
		
		// 4.前10个人丢弃
		emps.stream().skip(10).forEach(s -> System.out.println(s));
		System.out.println("------------------");
		
		// 5.是否有有奖金comm的员工
		boolean anyMatch = emps.stream().anyMatch(e -> e.getComm()!= 0);
		System.out.println(anyMatch);
		// 6.是否所有人的工资都超过1000元
		boolean allMatch = emps.stream().allMatch(e -> e.getSal()>=1000);
		System.out.println(allMatch);
	}

	@Test
	public void test2() {
		// filter
		// 1.得到所有salesman的员工
		emps.stream().filter(e -> e.getJob().equals("salesman")).forEach(e->System.out.println(e));
		System.out.println("---------------------");
		// 2.得到所有mgr是7698的员工
		emps.stream().filter(e -> e.getMgr() == 7698).forEach(e->System.out.println(e));
		System.out.println("---------------------");
		// 3.得到所有1981年5月1号之前入职的员工
		emps.stream().filter(e -> e.getHiredate().compareTo(LocalDate.of(1981, 5, 1)) < 0)
			.forEach(e->System.out.println(e));
		System.out.println("---------------------");
		// 4.10号部门的人数
		long count = emps.stream().filter(e -> e.getDeptno() == 10).count();
		System.out.println(count);
		System.out.println("---------------------");
		
		// reduce
		// 1.所有员工工资总和
		Optional<Emp> reduce = emps.stream().reduce((e1,e2)-> {
			Emp e = new Emp();
			e.setSal(e1.getSal() + e2.getSal());
			return e;
			});
		System.out.println(reduce.get().getSal());
		System.out.println("---------------------");
		// 2.20号部门的员工工资总和
		Optional<Emp> reduce2 = emps.stream().filter(e -> e.getDeptno() == 20)
					.reduce((e1,e2)-> {
						Emp e = new Emp();
						e.setSal(e1.getSal() + e2.getSal());
						return e;
						});
		System.out.println(reduce2.get().getSal());
		System.out.println("---------------------");
		
		// map
		// 1.前5个人的员工姓名大写后的姓名
		emps.stream().limit(5).map(e -> e.getEname().toUpperCase()).forEach(e->System.out.println(e));
		System.out.println("---------------------");
		// 2.把所有人的Sal都涨500
		emps.stream().map(e -> e.getSal() + 500).forEach(e->System.out.println(e));
		System.out.println("---------------------");
		// 3.每个员工年收入
		emps.stream().map(e -> e.getSal()*12 + e.getComm()).forEach(e->System.out.println(e));
		System.out.println("---------------------");
		
		
		// collect
		// 1.根据deptno分组
		emps.stream().collect(Collectors.groupingBy(e-> ((Emp)e).getDeptno()))
		                     .forEach((k,v)->System.out.println(k +"\n\t:" + v));
		System.out.println("---------------------");
		// 2.根据deptno分组，计算每个部门人数
		emps.stream().collect(Collectors.groupingBy(e-> ((Emp)e).getDeptno(),Collectors.counting()))
        	.forEach((k,v)->System.out.println(k +"\n\t:" + v));
		System.out.println("---------------------");
		// 3.返回每个部门工资最高的人
		emps.stream().collect(Collectors.groupingBy(e-> ((Emp)e).getDeptno(),
				Collectors.maxBy((e1,e2)->((Emp)e1).getSal() - ((Emp)e2).getSal())))
		    .forEach((k,v)->System.out.println(k +"\n\t:" + v));
		System.out.println("---------------------");
	}
}
